/**
 * 
 */
package nus.mtech.presentation;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.EtchedBorder;

import nus.mtech.ApplicationFacade;
import nus.mtech.customer.ComplaintManager;
import nus.mtech.customer.Customer;
import nus.mtech.constant.PresentationConstant;
import nus.mtech.util.DateUtil;
import javax.swing.JComboBox;
import javax.swing.JTextArea;
import nus.mtech.customer.Complaint;
import javax.swing.JTextField;

/**
 * @author Alvin Lee
 * 
 */
final class ComplaintPanel extends JPanel implements ActionListener {

	private Dimension screen = null;
	private static volatile ComplaintPanel INSTANCE;
	private JButton btnClear;
	private JButton btnUpdate;
	private JButton btnBack;
	private JComboBox comboBoxStatus;
	public JComboBox comboBoxDateTime;
	private JTextArea txtComplaint;
	private JTextArea txtFindings;
	private int compIDRef  = 0;
	private int runningCompID = 0;
	private JTextField txtCompAccNo;
	private JButton btnSearch;
	
	ComplaintPanel() {
		super(null);
		this.setBackground(PresentationConstant.CONSOLE_BACKGROUND);
		this.setPreferredSize(new Dimension(1004, 643));
		initialization();

	}

	public void initialization() {
		try {
			removeAll();

			screen = Toolkit.getDefaultToolkit().getScreenSize();

			final JLabel customerPanelLabel = new JLabel();
			customerPanelLabel.setHorizontalAlignment(SwingConstants.CENTER);
			customerPanelLabel.setFont(new Font("", Font.BOLD, 16));
			customerPanelLabel.setText("Manage Complaints");
			customerPanelLabel.setBounds(0, 10, 1004, 21);
			add(customerPanelLabel);

			JLabel borderBase = new JLabel();
			borderBase.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
			borderBase.setBounds(52, 62, 882, 527);
			add(borderBase);

			JLabel lblComplainDateTime = new JLabel("Date / Time:");
			lblComplainDateTime.setBounds(90, 173, 106, 14);
			add(lblComplainDateTime);

			btnClear = new JButton("Clear");
			btnClear.setBounds(275, 438, 89, 23);
			btnClear.addActionListener(this);
			add(btnClear);

			JLabel lblComplaintInfo = new JLabel("Complaint Information");
			lblComplaintInfo.setFont(new Font("Dialog", Font.BOLD, 14));
			lblComplaintInfo.setBounds(90, 88, 242, 21);
			add(lblComplaintInfo);

			JLabel lbComplaintInfo = new JLabel("Complaint:");
			lbComplaintInfo.setBounds(90, 210, 106, 14);
			add(lbComplaintInfo);

			JLabel lblFindings = new JLabel("Findings:");
			lblFindings.setBounds(90, 301, 106, 14);
			add(lblFindings);

			JLabel lblStatus = new JLabel("Status:");
			lblStatus.setBounds(90, 381, 106, 14);
			add(lblStatus);

			comboBoxStatus = new JComboBox();
			comboBoxStatus.setBounds(206, 378, 137, 20);
			//comboBoxStatus.addItem("");
			comboBoxStatus.addItem("Pending");
			comboBoxStatus.addItem("Closed");
			add(comboBoxStatus);

			btnUpdate = new JButton("Update / Add");
			btnUpdate.setBounds(126, 438, 106, 23);
			btnUpdate.addActionListener(this);
			add(btnUpdate);

			comboBoxDateTime = new JComboBox();
			comboBoxDateTime.setBounds(206, 170, 202, 20);
			comboBoxDateTime.addItem("Select Complaint");
			comboBoxDateTime.addActionListener(this);
			add(comboBoxDateTime);

			txtComplaint = new JTextArea();
			txtComplaint.setBounds(206, 210, 286, 67);
			add(txtComplaint);
			
			txtFindings = new JTextArea();
			txtFindings.setBounds(206, 296, 286, 67);
			add(txtFindings);
			
			btnBack = new JButton("Back");
			btnBack.setBounds(403, 438, 89, 23);
			btnBack.addActionListener(this);
			add(btnBack);
			
			JLabel lblAccountNumber = new JLabel("Account Number:");
			lblAccountNumber.setBounds(90, 129, 121, 16);
			add(lblAccountNumber);
			
			txtCompAccNo = new JTextField();
			txtCompAccNo.setBounds(206, 121, 158, 20);
			add(txtCompAccNo);
			txtCompAccNo.setColumns(10);
			//txtCompAccNo.setEditable(false);
			
			btnSearch = new JButton("Search");
			btnSearch.setBounds(397, 122, 89, 23);
			add(btnSearch);
			btnSearch.addActionListener(this);

		} catch (Exception ex) {
			System.out.println("exception");
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent ae) {
		// TODO Auto-generated method stub
		if (ae.getSource() == btnClear) {
			this.clear();	
			
		} else if (ae.getSource() == btnSearch){
			//TODO
			if (!this.validateAccountNoText()){
				this.clearComboBox();
				this.clearComplaintData();
				return;
			}
			
			this.populateComplaintData();
		}
		else if (ae.getSource() == btnBack) {
			Console.toggleCustomerSelectedPane(0);
		}else if (ae.getSource() == btnUpdate){
			//To do: Connect with complaint manager, merge the complaint date into the combobox	
			if (!this.validateAccountNoText()){
				this.clearComboBox();
				this.clearComplaintData();
				return;
			}
			
			if (!validateComplaintText()) {
				return;
			}
			
			//ver1
			//String accountNo = CustomerPanel.getInstance().getAccountNo();
			
			//ver2
			String accountNo = txtCompAccNo.getText();
			Date complaintDate = new Date();

			//if(compIDRef > 0){
			//Update
		   if (ApplicationFacade.getInstance().getComplaintByComplaintID(accountNo,compIDRef) != null){			   
							
				if (comboBoxStatus.getSelectedIndex() == 0)
				{
					ApplicationFacade.getInstance().updateComplaint(accountNo, compIDRef, txtFindings.getText(),true);
				}
					else
			    {
					ApplicationFacade.getInstance().updateComplaint(accountNo, compIDRef, txtFindings.getText(),false);
				}
				
							
				JOptionPane.showMessageDialog(this,"Updated into complaint list of the customer.", "Complaint Updated",
						JOptionPane.INFORMATION_MESSAGE);
			}else{
				runningCompID = ApplicationFacade.getInstance().getComplaintId();
				if (isValidAccountNo(accountNo)){
					Complaint comp = new Complaint(runningCompID,accountNo,complaintDate,txtComplaint.getText(),Console.getLoginUser().getUserID());
					comp.setComplaintFinding(txtFindings.getText());
					ApplicationFacade.getInstance().addNewComplaint(accountNo, comp);
				
					comboBoxDateTime.addItem(DateUtil.formatDate(complaintDate, DateUtil.DATE_TIME_FORMAT));
					
					JOptionPane.showMessageDialog(this,"New complaint has been added into complaint list of the customer.","New Complaint Added",
							JOptionPane.INFORMATION_MESSAGE);
					
					this.populateComplaintData();
					this.clearComplaintData();
				}else{
					JOptionPane.showMessageDialog(this,"The account number entered is invalid.","Invalid Account",
							JOptionPane.ERROR_MESSAGE);
				}
			}
			
			}else if (ae.getSource() == comboBoxDateTime){
				if ("comboBoxEdited".equals(ae.getActionCommand())) {
					//System.out.println("User has typed a string in the combobox.");
					} else if ("comboBoxChanged".equals(ae.getActionCommand())) {
					//System.out.println("User has selected an item from the combobox.");
					
					if(comboBoxDateTime.getSelectedIndex() > 0){
						//ver1
						//String accountNo = CustomerPanel.getInstance().getAccountNo();
						
						//ver2
						String accountNo = txtCompAccNo.getText();
						ArrayList<Complaint> compArray = ApplicationFacade.getInstance().getComplaintByAccountNo(accountNo);
						
						if (this.validateSearchResult(compArray)){
							for (Complaint comp:compArray){
								if (DateUtil.formatDate(comp.getComplaintDate(), DateUtil.DATE_TIME_FORMAT).equals(comboBoxDateTime.getSelectedItem())){
									txtComplaint.setText(comp.getComplaintDesc());
									txtFindings.setText(comp.getComplaintFinding());
									compIDRef = comp.getComplaintID();
									if(comp.getStatus() == true){
										comboBoxStatus.setSelectedIndex(0);
									}else{
										comboBoxStatus.setSelectedIndex(1);
									}
								}
							}
						}
						
					}else{
						compIDRef = -1;
						this.clearComplaintData();
					}
				}
			}
		}
	
	public void clearComplaintData() {
		comboBoxDateTime.setSelectedIndex(0);
		comboBoxStatus.setSelectedIndex(0);
		txtComplaint.setText("");
		txtFindings.setText("");
	}
	
	public void clearAccountNoText(){
		this.txtCompAccNo.setText("");
	}
	
	public static ComplaintPanel getInstance(){
		synchronized(ComplaintPanel.class){
			if (null == INSTANCE) {
				INSTANCE = new ComplaintPanel();
			}
			return INSTANCE;
		}
	}
	
	public void populateComplaintData() {
		this.clearComboBox();
		ArrayList<Complaint> compArray = ApplicationFacade.getInstance().getComplaintByAccountNo(txtCompAccNo.getText());
		
		if (this.validateSearchResult(compArray)){
			for (Complaint comp:compArray){
				comboBoxDateTime.addItem(DateUtil
						.formatDate(comp.getComplaintDate(),
								DateUtil.DATE_TIME_FORMAT));
			}
		}
	}
	
	public void clearComboBox(){
		while (comboBoxDateTime.getItemCount() > 1) {
			comboBoxDateTime.removeItemAt(1);
		}
	}
	
	private boolean validateAccountNoText(){
		if (txtCompAccNo.getText().trim().length() == 0){
			JOptionPane.showMessageDialog(this, "Please enter account number to search complaints.",
					"Account Number Required", JOptionPane.ERROR_MESSAGE);
			return false;
		}
		return true;
	}
	
	private boolean validateComplaintText(){
		if (txtComplaint.getText().trim().length() == 0){
			JOptionPane.showMessageDialog(this, "Please enter the complaint description.", 
						"Complaint Description Required",JOptionPane.ERROR_MESSAGE);
			return false;
		}
		return true;
	}
	
	private  boolean validateSearchResult(ArrayList<Complaint> compArray){
		if (null == compArray){
			JOptionPane.showMessageDialog(this, "No logged complaint found for account number provided.",
					 "Complaint Not Found",JOptionPane.ERROR_MESSAGE);
			return false;
		}
		return true;
	}
	
	public void setAccountNo(String accountNo){
		txtCompAccNo.setText(accountNo);
	}
	
	public void clear(){
		this.clearAccountNoText();
		this.clearComboBox();
		this.clearComplaintData();
	}
	
	private boolean isValidAccountNo(String accountNo){
		Customer cust = ApplicationFacade.getInstance().getCustomerByAccountNo(accountNo);
		
		if (null == cust){
			return false;
		}else{
			return true;
		}
	}
}
